package org.tis.tools.abf.module.om.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tis.tools.abf.module.common.entity.enums.YON;
import org.tis.tools.abf.module.om.controller.request.OmBatchDeleteRequest;
import org.tis.tools.abf.module.om.controller.request.OmPositionRequest;
import org.tis.tools.abf.module.om.dao.OmPositionMapper;
import org.tis.tools.abf.module.om.entity.*;
import org.tis.tools.abf.module.om.entity.enums.OmPositionStatus;
import org.tis.tools.abf.module.om.entity.enums.OmPositionType;
import org.tis.tools.abf.module.om.entity.vo.OmPositionDetail;
import org.tis.tools.abf.module.om.entity.vo.OmPositionForParentDetail;
import org.tis.tools.abf.module.om.exception.OMExceptionCodes;
import org.tis.tools.abf.module.om.exception.OrgManagementException;
import org.tis.tools.abf.module.om.service.*;
import org.tis.tools.core.utils.StringUtil;

import java.util.ArrayList;
import java.util.List;

import static org.tis.tools.core.utils.BasicUtil.wrap;

/**
 * omPosition的Service接口实现类
 * 
 * @author Auto Generate Tools
 * @date 2018/04/23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OmPositionServiceImpl extends ServiceImpl<OmPositionMapper, OmPosition> implements IOmPositionService {

    @Autowired
    private IOmOrgService omOrgService;
    @Autowired
    private IOmGroupService omGroupService;
    @Autowired
    private IOmEmployeeService omEmployeeService;
    @Autowired
    private IOmEmpPositionService omEmpPositionService;
    @Autowired
    private IOmPositionAppService omPositionAppService;


    @Override
    public boolean addRoot(OmPositionRequest omPositionRequest) throws OrgManagementException {

        OmPosition omPosition = new OmPosition();

        // 补充父岗位，根节点没有父岗位
        omPosition.setGuidParents("");
        // 新增节点都先算叶子节点 Y
        omPosition.setIsleaf(YON.YES);
        if (omPositionRequest.getPositionType().equals(OmPositionType.ORGANIZATION.toString())){
            OmOrg omOrg = omOrgService.selectById(omPositionRequest.getGuidMapping());
            if (null == omOrg){
                throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_ORG);
            }
        }
        if (omPositionRequest.getPositionType().equals(OmPositionType.WORKINGGROUP.toString())){
            OmGroup omGroup = omGroupService.selectById(omPositionRequest.getGuidMapping());
            if (null == omGroup){
                throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_GROUP);
            }
        }
        //新建岗位为正常状态
        omPosition.setPositionStatus(OmPositionStatus.RUNNING);
        omPosition.setGuidMapping(omPositionRequest.getGuidMapping());
        omPosition.setPositionCode(omPositionRequest.getPositionCode());
        omPosition.setPositionName(omPositionRequest.getPositionName());
        omPosition.setPositionType(omPositionRequest.getPositionType());
        omPosition.setSubCount(omPositionRequest.getSubCount());
        omPosition.setPositionLevel(omPositionRequest.getPositionLevel());
        omPosition.setPositionSeq(omPositionRequest.getPositionSeq());
        omPosition.setStartDate(omPositionRequest.getStartDate());
        omPosition.setEndDate(omPositionRequest.getEndDate());

        insert(omPosition);
        return true;
    }


    @Override
    public boolean addChild(OmPositionRequest omPositionRequest) throws OrgManagementException {

        //查询父岗位信息
        OmPosition omPositionRoot = selectById(omPositionRequest.getGuidParents());
        if(omPositionRoot == null) {
            throw new OrgManagementException(
                    OMExceptionCodes.POSITION_NOT_EXIST_BY_POSITION_CODE, wrap(omPositionRequest.getGuidParents()));
        }
        if (omPositionRequest.getPositionType().equals(OmPositionType.ORGANIZATION.toString())){
            OmOrg omOrg = omOrgService.selectById(omPositionRequest.getGuidMapping());
            if (null == omOrg){
                throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_ORG);
            }
        }
        if (omPositionRequest.getPositionType().equals(OmPositionType.WORKINGGROUP.toString())){
            OmGroup omGroup = omGroupService.selectById(omPositionRequest.getGuidMapping());
            if (null == omGroup){
                throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_GROUP);
            }
        }

        OmPosition omPosition = new OmPosition();

        // 新增节点都先算叶子节点 Y
        omPosition.setIsleaf(YON.YES);
        //新建岗位为正常状态
        omPosition.setPositionStatus(OmPositionStatus.RUNNING);
        omPosition.setGuidMapping(omPositionRequest.getGuidMapping());
        omPosition.setPositionCode(omPositionRequest.getPositionCode());
        omPosition.setPositionName(omPositionRequest.getPositionName());
        omPosition.setPositionType(omPositionRequest.getPositionType());
        omPosition.setSubCount(omPositionRequest.getSubCount());
        omPosition.setPositionLevel(omPositionRequest.getPositionLevel());
        omPosition.setPositionSeq(omPositionRequest.getPositionSeq());
        omPosition.setStartDate(omPositionRequest.getStartDate());
        omPosition.setEndDate(omPositionRequest.getEndDate());
        omPosition.setGuidParents(omPositionRequest.getGuidParents());

        // 更新父节点机构 是否叶子节点 节点数 最新更新时间 和最新更新人员
        omPositionRoot.setIsleaf(YON.NO);
        insert(omPosition);
        updateById(omPositionRoot);

        return true;
    }


    @Override
    public OmPosition change(OmPositionRequest omPositionRequest) throws OrgManagementException {

        OmPosition omPosition = new OmPosition();
        omPosition.setGuid(omPositionRequest.getGuid());
        omPosition.setGuidMapping(omPositionRequest.getGuidMapping());
        omPosition.setPositionCode(omPositionRequest.getPositionCode());
        omPosition.setPositionName(omPositionRequest.getPositionName());
        omPosition.setPositionType(omPositionRequest.getPositionType());
        omPosition.setPositionStatus(omPositionRequest.getPositionStatus());
        omPosition.setSubCount(omPositionRequest.getSubCount());
        omPosition.setPositionLevel(omPositionRequest.getPositionLevel());
        omPosition.setPositionSeq(omPositionRequest.getPositionSeq());
        omPosition.setStartDate(omPositionRequest.getStartDate());
        omPosition.setEndDate(omPositionRequest.getEndDate());
        omPosition.setGuidParents(omPositionRequest.getGuidParents());
        omPosition.setIsleaf(omPositionRequest.getIsleaf());

        updateById(omPosition);
        return omPosition;
    }


    @Override
    public OmPositionDetail queryPositionTree(String id) throws OrgManagementException {


        OmPosition omPosition = selectById(id);

        //查询子功能字典
        Wrapper<OmPosition> wrapper = new EntityWrapper<OmPosition>();
        wrapper.eq(OmPosition.COLUMN_GUID_PARENTS,id);
        wrapper.orderBy(OmPosition.COLUMN_CREATETIME);

        List<OmPosition> queryList = selectList(wrapper);

        //收集参数
        OmPositionDetail omPositionDetail = new OmPositionDetail(omPosition,queryList);

        return omPositionDetail;
    }


    @Override
    public void deleteRoot(String id) throws OrgManagementException {

        if (StringUtil.isNotEmpty(id)){
            //删除父岗位下的所有子岗位
            deleteAllChild(id);
        }
    }

    /**
     * 批量删除岗位
     */
    @Override
    public void batchDelete(OmBatchDeleteRequest deleteRequest) throws OrgManagementException {
        if (0 == deleteRequest.getDeleteList().size()){
            throw new OrgManagementException(OMExceptionCodes.PARAMETER_IS_EMPTY_WHRN_BATCH_DELETE,wrap("删除时参数列表为空"));
        }

        for (String positionGuid : deleteRequest.getDeleteList()){
            if (!StringUtil.isEmpty(positionGuid)){
                OmPosition omPosition = selectById(positionGuid);
                if (null == omPosition){
                    throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_POSITION,wrap
                            ("查询的岗位不存在或已删除！"));
                }
            }
        }

        for(String positionGuid : deleteRequest.getDeleteList()){
            if (null != positionGuid){
                deleteEmpPosition(positionGuid);
                deleteAppPosition(positionGuid);
                deleteById(positionGuid);
            }
        }
    }

    //删除父岗位下的所有子岗位
    private void deleteAllChild(String id){
        //首先删除父岗位对应的子岗位
        Wrapper<OmPosition> wrapper = new EntityWrapper<OmPosition>();
        wrapper.eq(OmPosition.COLUMN_GUID_PARENTS,id);

        //获取子岗位列表
        List<OmPosition> lists = selectList(wrapper);

        if (0 == lists.size()){
            deleteById(id);
            deleteEmpPosition(id);
            deleteAppPosition(id);
        }else {
            for (OmPosition omPosition :lists){
                if (!StringUtil.isEquals(omPosition.getGuid(),omPosition.getGuidParents())){
                    deleteAllChild(omPosition.getGuid());
                }
                deleteEmpPosition(id);
                deleteAppPosition(id);
            }
            deleteById(id);
            deleteEmpPosition(id);
            deleteAppPosition(id);
        }
    }

    /** 删除岗位和员工的关系信息 */
    private void deleteEmpPosition(String id) throws OrgManagementException {

        Wrapper<OmEmpPosition> wrapper = new EntityWrapper<OmEmpPosition>();
        wrapper.eq(OmEmpPosition.COLUMN_GUID_POSITION,id);

        List<OmEmpPosition> list = omEmpPositionService.selectList(wrapper);
        if ( 0 != list.size()){
            omEmpPositionService.delete(wrapper);
        }
    }

    /** 删除岗位和应用的关系信息 */
    private void deleteAppPosition(String id)throws OrgManagementException{

        Wrapper<OmPositionApp> wrapper = new EntityWrapper<OmPositionApp>();
        wrapper.eq(OmPositionApp.COLUMN_GUID_POSITION,id);
        List<OmPositionApp> list = omPositionAppService.selectList(wrapper);
        if (0 != list.size()){
            omPositionAppService.delete(wrapper);
        }
    }

    /**
     * 根据岗位ID查询机构
     */
    @Override
    public Page<OmPositionForParentDetail> treeByOrgId(Page<OmPosition> page, Wrapper<OmPosition> wrapper, String id) throws
            OrgManagementException {

        OmOrg omOrg = omOrgService.selectById(id);
        if (omOrg == null){
            throw new OrgManagementException(OMExceptionCodes.FAILURE_WHEN_QUERY_OM_ORG,wrap("组织机构ID对应的组织机构不存在",id));
        }

        if (null == wrapper.getEntity()){
            wrapper = new EntityWrapper<OmPosition>();
        }

        wrapper.eq(OmPosition.COLUMN_GUID_MAPPING,id);
        wrapper.orderBy(OmPosition.COLUMN_POSITION_LEVEL,true);
        wrapper.orderBy(OmPosition.COLUMN_POSITION_SEQ,true);
        Page<OmPosition> pageQuuery = selectPage(page,wrapper);
        List<OmPosition> list = pageQuuery.getRecords();

        Page<OmPositionForParentDetail> pageParent = new Page<OmPositionForParentDetail>();
        List<OmPositionForParentDetail> listParent = new ArrayList<OmPositionForParentDetail>();

        for (OmPosition omPosition : list){
            if (null != omPosition){
                //查询对应机构且在该岗位下的员工数
                int employeeCountQue = 0;
                employeeCountQue = this.baseMapper.queryEmpCountByOrgPosition(omPosition.getGuid());

                //查询出父岗位的名称
                String parentNameQue = "";
                if (StringUtil.isNotEmpty(omPosition.getGuidParents())){
                    parentNameQue = this.baseMapper.queryParentName(omPosition.getGuidParents());
                }

                OmPositionForParentDetail omPositionForParentDetail = new OmPositionForParentDetail(omPosition,
                        parentNameQue, employeeCountQue);
                listParent.add(omPositionForParentDetail);
            }
        }

        pageParent.setRecords(listParent);
        pageParent.setCurrent(pageQuuery.getCurrent());
        pageParent.setSize(pageQuuery.getSize());
        pageParent.setTotal(pageQuuery.getTotal());

        return pageParent;
    }


    @Override
    public List<OmPosition> QueryAllPosition() throws OrgManagementException {

        Wrapper<OmPosition> wrapper = new EntityWrapper<>();
        List<OmPosition> list = selectList(wrapper);

        return list;
    }


    @Override
    public List<OmPosition> QueryPositionByOrgId(String orgId,String guid) throws OrgManagementException {

        Wrapper<OmPosition> wrapper = new EntityWrapper<OmPosition>();
        wrapper.eq(OmPosition.COLUMN_GUID_MAPPING,orgId);
        List<OmPosition> list = selectList(wrapper);

        if (0 != list.size()){
            if (StringUtil.isNotEmpty(guid)){
                OmPosition omPosition = selectById(guid);
                if (null != omPosition){
                    list.remove(omPosition);
                }
            }
        }

        return list;
    }

    /**
     * 判断新增时岗位代码是否存在
     */
    @Override
    public Boolean existAddPositionCode(String positionCode, String guidMapping) throws OrgManagementException {

        Wrapper<OmPosition> wrapper = new EntityWrapper<OmPosition>();
        wrapper.eq(OmPosition.COLUMN_POSITION_CODE,positionCode);
        wrapper.eq(OmPosition.COLUMN_GUID_MAPPING,guidMapping);

        List<OmPosition> positionList = selectList(wrapper);
        if (0 != positionList.size()){
            return true;
        }

        return false;
    }

    /**
     * 判断修改时岗位代码是否存在
     */
    @Override
    public Boolean existUpdatePositionCode(String positionCode ,String guid, String guidMapping) throws
            OrgManagementException {

        Wrapper<OmPosition> wrapper = new EntityWrapper<OmPosition>();
        wrapper.eq(OmPosition.COLUMN_POSITION_CODE,positionCode);
        wrapper.eq(OmPosition.COLUMN_GUID_MAPPING,guidMapping);

        List<OmPosition> positionList = selectList(wrapper);
        if (0 != positionList.size()){
            OmPosition omPosition = selectById(guid);
            if (null != omPosition){
                positionList.remove(omPosition);
                if (0 != positionList.size()){
                    return true;
                }
            }
        }

        return false;
    }
}

